﻿using System.Collections.Concurrent;
using WeDonekRpc.PipeServer.Interface;
using WeDonekRpc.PipeServer.Log;
using WeDonekRpc.PipeServer.Model;
using WeDonekRpc.PipeServer.Server;

namespace WeDonekRpc.PipeServer.Manage
{
    internal class ReplyPageManage
    {
        private static readonly ConcurrentDictionary<uint, ReplyPage> _DataPageList = new ConcurrentDictionary<uint, ReplyPage>();

        public static void Send (GetDataPage arg, object data)
        {
            ReplyPage page = Page.GetReplyPage(arg, data);
            if (_DataPageList.TryAdd(page.PageId, page))
            {
                if (!arg.Client.Send(page.Page, page.PageId))
                {
                    _RetrySend(page);
                }
            }
            else
            {
                IoLogSystem.AddReplyError(page, "pipe.server.reply.error");
            }
        }
        public static void ComplateSend (uint pageId)
        {
            _ = _DataPageList.TryRemove(pageId, out _);
        }
        public static void SendError (uint pageId)
        {
            if (_DataPageList.TryGetValue(pageId, out ReplyPage page))
            {
                _RetrySend(page);
            }
        }
        private static void _SendError (uint pageId, string error)
        {
            if (_DataPageList.TryRemove(pageId, out ReplyPage page))
            {
                IoLogSystem.AddReplyError(page, error);
            }
        }
        private static void _RetrySend (ReplyPage page)
        {
            page.RetryNum += 1;
            if (page.RetryNum > Config.PipeConfig.ReplyRetryNum)
            {
                _SendError(page.Page.PageId, "pipe.reply.error");
                return;
            }
            if (PipeServer.GetServer(page.Client.PipeName, out ServerInfo server))
            {
                IClient client = server.FindClient(page.Client.BindParam);
                if (client == null)
                {
                    _SendError(page.Page.PageId, "pipe.client.con.null");
                }
                else if (!client.Send(page.Page, page.PageId))
                {
                    _RetrySend(page);
                }
            }
        }
    }
}
